package com.example.demo.utils;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Map;

import org.springframework.stereotype.Component;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;
import com.mashape.unirest.http.exceptions.UnirestException;

//import org.apache.commons.collections.MapUtils;

//import lombok.extern.slf4j.Slf4j;

/**
 * http请求工具类
 */
@Component
//@Slf4j
public class UnirestUtil {

    private static final ObjectMapper JSON     = new ObjectMapper();

    static {
        JSON.configure(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS, true);
        JSON.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        JSON.configure(DeserializationFeature.READ_ENUMS_USING_TO_STRING, true);
        JSON.configure(SerializationFeature.WRITE_ENUMS_USING_TO_STRING, true);

        JSON.setSerializationInclusion(JsonInclude.Include.NON_NULL);

        JSON.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));

        Unirest.setObjectMapper(new com.mashape.unirest.http.ObjectMapper() {
            @Override
            public <T> T readValue(String s, Class<T> aClass) {
                try {
                    return JSON.readValue(s,aClass);
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }

            @Override
            public String writeValue(Object o) {
                try {
                    return JSON.writeValueAsString(o);
                } catch (JsonProcessingException e) {
                    throw new RuntimeException(e);
                }
            }

        });
    }

    /**
     * get请求
     * @param url
     * @return
     * @throws UnirestException
     */
    public static String get(String url) throws UnirestException {
        return get(url,null);
    }

    /**
     * get请求
     * @param url
     * @param parameters
     * @param respClass
     * @param <T>
     * @return
     * @throws UnirestException
     */
    public static <T> T get(String url,Map<String,Object> parameters,Class<T> respClass) throws UnirestException {
//        log.info("==>http get begin,url={}, parameters={},respClass={}",url,mapToString(parameters),respClass.getCanonicalName());
        HttpResponse<T> response = Unirest.get(url)
                .header("accept", "application/json")
                .queryString(parameters)
                .asObject(respClass);
        T object = response.getBody();
//        log.info("==>http get end,resp={}", JSONObject.toJSONString(object));
        return object;
    }

    /**
     * get请求
     * @param url
     * @param parameters
     * @return
     * @throws UnirestException
     */
    public static String get(String url,Map<String,Object> parameters) throws UnirestException {
//        log.info("==>http get begin,url={}, parameters={}",url,mapToString(parameters));
        HttpResponse<String> response = Unirest.get(url)
                .header("accept", "application/json")
                .queryString(parameters)
                .asString();
        String resMsg = response.getBody();
//        log.info("==>http get end,resp={}",resMsg);
        return resMsg;
    }

    /**
     * Post请求
     * @param url
     * @param requestBody
     * @param respClass
     * @param <T>
     * @return
     * @throws UnirestException
     */
    public static <T> T post(String url,Object requestBody,Class<T> respClass) throws UnirestException {
//        log.info("==>http post begin,url={}, requestBody={},respClass={}",url, JSONObject.toJSONString(requestBody),respClass.getCanonicalName());
        HttpResponse<T> response = Unirest.post(url)
                .header("accept", "application/json")
                .header("Content-Type", "application/json")
                .body(requestBody)
                .asObject(respClass);
        T object = response.getBody();
//        log.info("==>http post end,resp={}", JSONObject.toJSONString(object));
        return object;
    }


    public static <T> T post(String url, Map<String,Object> parameters, Object requestBody,Class<T> respClass) throws UnirestException {
        HttpResponse<T> response = Unirest.post(url)
                .header("accept", "application/json")
                .header("Content-Type", "application/json")
                .queryString(parameters)
                .body(requestBody)
                .asObject(respClass);
        T object = response.getBody();
        return object;
    }

    /**
     * 表单提交
     * @param url
     * @param requestBody
     * @param respClass
     * @param <T>
     * @return
     * @throws UnirestException
     */
    public static <T> T postForm(String url,Map<String,Object> requestBody,Class<T> respClass) throws UnirestException {
//        log.info("==>http postForm begin,url={}, requestBody={},respClass={}",url, JSONObject.toJSONString(requestBody),respClass.getCanonicalName());
        HttpResponse<T> response = Unirest.post(url)
                .header("Content-Type", "application/x-www-form-urlencoded")
                .fields(requestBody)
                .asObject(respClass);
        T object = response.getBody();
//        log.info("==>http postForm end,resp={}", JSONObject.toJSONString(object));
        return object;
    }


    /**
     * Map 转化为String
     * @param map
     * @return
     */
    public static String mapToString(Map<String,Object> map){
        if (map == null || map.size() == 0){
//        if(MapUtils.isEmpty(map)){
            return "";
        }
        StringBuffer stringBuffer = new StringBuffer("[");
        for (Map.Entry<String, Object> entry : map.entrySet()) {
            stringBuffer.append(entry.getKey()).append(" : ").append(entry.getValue().toString()).append("; ");
        }
        stringBuffer.append("]");
        return stringBuffer.toString();
    }
}
